package com.hanko.rabbitmq;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class MyAckReceiver implements ChannelAwareMessageListener {
    boolean basicNack = true;

    /**
     * 消费者，消费时可以手动ACK，或丢回消息队列，或者直接丢弃
     * @param message
     * @param channel
     * @throws Exception
     */
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            //因为传递消息的时候用的map传递,所以将Map从Message内取出需要做些处理
            String msg = message.toString();
            //可以点进Message里面看源码,单引号直接的数据就是我们的map消息数据
            String[] msgArray = msg.split("'");
            System.out.println("消费的主题消息来自："+message.getMessageProperties().getConsumerQueue());
            System.out.println("消费的消息内容:"+msgArray[1]);

            /*
             * 肯定确认
             * deliveryTag：消息队列数据的唯一id
             * multiple：是否批量
             * true ：一次性确认所有小于等于deliveryTag的消息
             * false：对当前消息进行确认；
             */
//            channel.basicAck(deliveryTag, false);
            /*
             * 否定确认
             * multiple：是否批量 
             *   true：一次性拒绝所有小于deliveryTag的消息
             *   false：对当前消息进行确认；
             * requeue：被拒绝的是否重新入列，
             *   true：就是将数据重新丢回队列里，那么下次还会消费这消息；
             *   false：就是拒绝处理该消息，服务器把该消息丢掉即可。 
             */

            /*if(basicNack){
                log.info("---------------消息重新放回队列----------------------");
                channel.basicNack(deliveryTag, false, true);
                basicNack = false;
            }else {
                log.info("---------------二次消息被ACK----------------------");
                channel.basicAck(deliveryTag, false);
                //复位标识值
                basicNack = true;
            }*/

            /*
             * 用于否定确认，但与basicNack相比有一个限制,一次只能拒绝单条消息
             */
//            channel.basicReject(deliveryTag, false);

        } catch (Exception e) {
            //丢弃消息，拒绝重新入队列
            channel.basicReject(deliveryTag, false);
            e.printStackTrace();
        }
    }
}
